/**
 * 文件组件,以表格的形式查看文件文件列表,支持上传,删除,预览,批量下载
 * 添加了disabled属性,为true时不显示上传和删除的按钮
 * 支持最大的文件数量
 * 支持table的高度定义,height属性,使用与el-table一致
 * 有一系列的事件钩子,详情参照props
 * 设计思路:
 * 1. 文件回显: 双向绑定fileVos
 * 2. 文件上传: 上传成功后往fileVos中push新的文件
 * 3. 文件删除: 将fileVos中对应对象删除
 * 4. 文件预览: 目前是图片,视频可以预览
 * 5. 文件批量下载: 多选文件,下载
 *
 */
// 文件类型
import fileApi from '@/api/file/fileApi'
import validate from '@/common/validate'
import {convertAmrToWav} from '@/common/amr/amr.js'

const IMAGE = 'image'
const VIDEO = 'video'
const AUDIO = 'audio'
const extensionTypeMap = {
  'jpg': IMAGE,
  'jpeg': IMAGE,
  'png': IMAGE,
  'gif': IMAGE,
  'bmp': IMAGE,

  'mp4': VIDEO,
  'mkv': VIDEO,
  'avi': VIDEO,
  'mov': VIDEO,
  'wmv': VIDEO,
  'flv': VIDEO,

  'mp3': AUDIO,
  'wav': AUDIO,
  'ogg': AUDIO,
  'aac': AUDIO,
  'm4a': AUDIO,
  'amr': AUDIO,


  // ... 更多文件类型的映射
}

function noop() {
}

export default {
  name: 'zUploadTable',

  props: {
    value: [],
    height: {
      required: false,
      default: '500px'
    },
    limit: {
      type: Number,
      required: false,
    },
    type: Array,
    'before-upload': {
      required: false,
      type: Function,
      default: noop
    },
    'on-error': {
      required: false,
      type: Function,
      default: noop,
    },
    'on-success': {
      required: false,
      type: Function,
      default: noop,
    },
    'on-exceed': {
      required: false,
      type: Function,
      default: noop
    },
    disabled: {
      required: false,
      type: Boolean,
      default: false,
    }
  },
  data() {
    return {
      // 当前文件选中项
      multipleSelection: [],
      // 预览相关
      preview: {
        visible: false,
        width: '50%',
        fileType: '',
        title: '预览',
        path: ''
      },
      // 当前操作行
      currentRow: null,
      options: {
        fileType: {
          AUDIO,
          VIDEO,
          IMAGE
        }
      }
    }
  },
  methods: {
    // 表格多选事件
    handleSelectionChange(selections) {
      this.multipleSelection = selections
    },
    // 点击上传按钮的事件
    handleUpload() {
      // 手动触发文件选择事件
      this.$refs['fileUpload'].click()
    },
    // 文件选取变化事件,目前仅支持单文件上传
    handleFileChange() {
      let {target} = event
      let files = target.files
      // 如果file为null,那么说明没有选取文件,那么无需上传.
      if (!files) {
        return
      }
      // 多个文件的话不允许上传
      if (validate.isNumber(this.limit) && this.limit < this.value.list + files.length) {
        this.onExceed({files})
      }
      // 注意,每次文件上传的操作时都需要将input赋为空,因为监听的是change事件,避免选择反复同一文件不能触发上传.
      if (typeof this.beforeUpload === 'function') {
        // 上传前的钩子
        let res = this.beforeUpload({files})
        if (res === false) {
          return
        } else if (res && res.then) {
          res.then(() => {
            this.upload(files)
          })
        } else {
          this.upload(files)
        }
      } else {
        this.upload(files)
      }
      this.$refs['fileUpload'].value = null
    },
    // 文件上传
    upload(files) {
      fileApi.uploads(files).then(res => {
        // 如果文件上传成功,那么直接加入到当前文件列表中
        this.$emit('input', [...this.value, ...res.data])
        if (typeof this.onSuccess === 'function') {
          this.$message.success('上传成功')
          // 上传成功钩子
          this.onSuccess({files, res})
        }
      }).catch(err => {
        // 上传失败钩子
        if (typeof this.onError === 'function') {
          this.onError({files, err: err})
        }
      })
    },
    // 预览
    async handlePreview(row) {
      this.currentRow = row
      let fileType = extensionTypeMap[row.fileType]
      switch (fileType) {
        case VIDEO:
          this.preview.path = row.path
          this.preview.fileType = VIDEO
          this.preview.visible = true
          break
        case AUDIO:
          if(row.fileType === 'amr'){
            this.preview.path = await convertAmrToWav(row.path)
          }else{
            this.preview.path = row.path
          }
          this.preview.fileType = AUDIO
          this.preview.visible = true
          break
        case IMAGE:
          this.preview.path = row.path
          this.preview.fileType = IMAGE
          this.preview.visible = true
          break
        default:
          this.$message.warning('不支持的文件类型,请下载后查看')
      }
    },
    handlePreviewClose() {
      this.preview.visible = false
    },
    // 单文件下载
    handleDownload(row) {
      if (row.path) {
        this.$rq.downloadFileStream(row.path, {}, row.fileName)
      } else {
        this.$message.warning('文件下载路径不存在')
      }
    },
    // 多选下载
    handleDownloadMultiple() {
      if (this.multipleSelection.length) {
        // todo
        let filePaths = this.multipleSelection.map(e => e.path)
        fileApi.downloadZip({filePaths}).then(res => {

        })
      } else {
        this.$message.warning('请选择至少一个文件')
      }
    },
    // 删除
    handleDel() {
      if(this.multipleSelection.length){
        this.$confirm('确认删除?', {
          title: '提示',
          confirmButtonText: '删除',
          type: 'warning',
          callback: (action) => {
            if (action == 'confirm') {
              let idsTodel = this.multipleSelection.map(e => e.id)
              this.$emit('input',this.value.filter(e => !idsTodel.includes(e.id)))
            }
          }
        })
      }else{
        this.$message.warning('请至少选择一行')
      }
    },
    fileSizeFormatter(row){
      return this.computeFileSize(row.fileSize)
    },
    // 计算文件大小
    computeFileSize(_fileSize) {
      let res = ''
      let fileSize = Number.parseInt(_fileSize)
      if (Number.isSafeInteger(fileSize)) {
        // 单位
        let unit = ['B', 'KB', 'M', 'G']
        // 进制
        let carriage = 1024
        for (let i = 0; i < unit.length; i++ , fileSize /= carriage) {
          if (fileSize < carriage) {
            res = `${fileSize.toFixed(2)}${unit[i]}`
            break
          }
        }
      }
      return res
    },
    // 表格行点击事件
    handleRowClick(row) {
      this.$refs.table.toggleRowSelection(row)
    },
  }
}
